import { AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChange, SimpleChanges, ViewChild } from '@angular/core';

@Component({
  selector: 'app-person',
  templateUrl: './person.component.html',
  styles: [
  ]
})
export class PersonComponent 
  implements OnInit, AfterContentInit, AfterViewInit, OnChanges, AfterContentChecked, AfterViewChecked, OnDestroy {
  // 正确写法
  // @Input("name") name: string = ''
  // // 缩略写法 当属性名与变量名相同时能省略属性名
  // @Input() age: string = '0'

  // // 使用 Output 装饰器将 emit 方法导出子组件
  // @Output() sendData = new EventEmitter()
  // constructor() { }

  // ngOnInit(): void {
  // }
  // onClick () {
  //   this.sendData.emit('我是子组件的数据')
  // }
  @Input () name : string = ''
  @Input () age : string = ''
  @Input () person = { name: '' }
  @ContentChild('box') box: ElementRef<HTMLDivElement> | undefined
  @ViewChild('p') p: ElementRef<HTMLProgressElement> | undefined

  constructor() { 
    // 组件类的构造函数 最快执行
    // 推荐只接受服务实例对象
    console.log('constructor')
    console.log(this.name) // ''
  }
  ngOnInit() {
    // 首次接收到输入属性值后 第二个执行
    console.log('ngOnInit')
    console.log(this.name) // 'zhangsan'
  }
  ngAfterContentInit () {
    // 内容投影初始化完成后  可以获取到内部的元素 第三个执行
    console.log('ngAfterContentInit')
    console.log(this.box) // ElementRef {}
  }
  ngAfterViewInit () {
    // 当组件视图渲染完成后调用 可以获取当前组件元素 第四个执行
    console.log('ngAfterViewInit')
    console.log(this.p) // ElementRef {}
  }
  ngOnChanges (changes: SimpleChanges) {
    // 当数据发生变化时执行，初始化时也会执行一次
    // 同时修改 name 和 age，只执行一次,发生变化的数据都会保存在 changes 中
    // 如果是引用类型中的值发生变化，视图会变化但方法不会被触发，如果是引用地址改变就会触发方法
    console.log('ngOnChanges')
    console.log(changes)
  }
  ngAfterContentChecked () {
    console.log('内容')
  }
  ngAfterViewChecked () {
    console.log('视图')
  }
  ngOnDestroy () {
    // 一般会处理事件行为与定时器等
    console.log('组件被卸载')
  }
}
